﻿namespace CpuUsageAPI
{
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Drawing;
    using System.Windows.Forms;

    public class Example : Form
    {
        private ColumnHeader columnHeader1;
        private ColumnHeader columnHeader2;
        private ColumnHeader columnHeader3;
        private IContainer components = null;
        private ListViewItem IdleProcessItem;
        private ArrayList IDList = new ArrayList();
        private const ProcessData PROCESS_DATA_NOT_FOUND = null;
        private const ListViewItem PROCESS_ITEM_NOT_FOUND = null;
        private ArrayList ProcessDataList = new ArrayList();
        private ListView ProcessView;
        private Timer UsageTimer;

        public Example()
        {
            this.InitializeComponent();
            base.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.SupportsTransparentBackColor | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true);
        }

        private void AddProcess(ProcessData NewProcess)
        {
            ListViewItem item = this.ProcessView.Items.Add(NewProcess.Name);
            item.SubItems.Add(NewProcess.ID.ToString());
            item.SubItems.Add("0%");
            NewProcess.ProcessItem = item;
            if (NewProcess.ID == 0)
            {
                this.IdleProcessItem = item;
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (this.components != null))
            {
                this.components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void GetUsage()
        {
            ProcessEntry32 processInfo = new ProcessEntry32();
            ProcessTimes times = new ProcessTimes();
            IntPtr processHandle = ProcessCPU.PROCESS_HANDLE_ERROR;
            int num2 = 0;
            IntPtr handle = ProcessCPU.CreateToolhelp32Snapshot(2, 0);
            if (handle != ProcessCPU.PROCESS_LIST_ERROR)
            {
                int num;
                processInfo.Size = 0x128;
                bool flag = ProcessCPU.Process32First(handle, ref processInfo);
                this.IDList.Clear();
                this.ProcessView.SuspendLayout();
                while (flag)
                {
                    try
                    {
                        processHandle = ProcessCPU.OpenProcess(0x1f0fff, false, processInfo.ID);
                        ProcessCPU.GetProcessTimes(processHandle, out times.RawCreationTime, out times.RawExitTime, out times.RawKernelTime, out times.RawUserTime);
                        times.ConvertTime();
                        ProcessData data = this.ProcessExists(processInfo.ID);
                        this.IDList.Add(processInfo.ID);
                        if (data == null)
                        {
                            num = this.ProcessDataList.Add(new ProcessData(processInfo.ID, processInfo.ExeFilename, times.UserTime.Ticks, times.KernelTime.Ticks));
                            this.AddProcess((ProcessData) this.ProcessDataList[num]);
                        }
                        else
                        {
                            num2 += data.UpdateCpuUsage(times.UserTime.Ticks, times.KernelTime.Ticks);
                        }
                    }
                    finally
                    {
                        if (processHandle != ProcessCPU.PROCESS_HANDLE_ERROR)
                        {
                            ProcessCPU.CloseHandle(processHandle);
                        }
                        flag = ProcessCPU.Process32Next(handle, ref processInfo);
                    }
                }
                ProcessCPU.CloseHandle(handle);
                num = 0;
                while (num < this.ProcessDataList.Count)
                {
                    ProcessData data2 = (ProcessData) this.ProcessDataList[num];
                    if (this.IDList.Contains(data2.ID))
                    {
                        num++;
                    }
                    else
                    {
                        this.ProcessView.Items.Remove(data2.ProcessItem);
                        this.ProcessDataList.RemoveAt(num);
                    }
                }
                this.IdleProcessItem.SubItems[2].Text = (100 - num2) + "%";
                this.ProcessView.ResumeLayout();
            }
        }

        private void InitializeComponent()
        {
            this.components = new Container();
            this.UsageTimer = new Timer(this.components);
            this.ProcessView = new ListView();
            this.columnHeader1 = new ColumnHeader();
            this.columnHeader2 = new ColumnHeader();
            this.columnHeader3 = new ColumnHeader();
            base.SuspendLayout();
            this.UsageTimer.Enabled = true;
            this.UsageTimer.Interval = 0x3e8;
            this.UsageTimer.Tick += new EventHandler(this.UsageTimer_Tick);
            this.ProcessView.Columns.AddRange(new ColumnHeader[] { this.columnHeader1, this.columnHeader2, this.columnHeader3 });
            this.ProcessView.Dock = DockStyle.Fill;
            this.ProcessView.FullRowSelect = true;
            this.ProcessView.Location = new Point(0, 0);
            this.ProcessView.Name = "ProcessView";
            this.ProcessView.Size = new Size(0x184, 0x113);
            this.ProcessView.Sorting = SortOrder.Ascending;
            this.ProcessView.TabIndex = 0;
            this.ProcessView.UseCompatibleStateImageBehavior = false;
            this.ProcessView.View = View.Details;
            this.columnHeader1.Text = "Process Name";
            this.columnHeader1.Width = 0xca;
            this.columnHeader2.Text = "PID";
            this.columnHeader2.TextAlign = HorizontalAlignment.Right;
            this.columnHeader2.Width = 0x4d;
            this.columnHeader3.Text = "Cpu Usage %";
            this.columnHeader3.TextAlign = HorizontalAlignment.Right;
            this.columnHeader3.Width = 0x68;
            base.AutoScaleDimensions = new SizeF(6f, 13f);
            base.AutoScaleMode = AutoScaleMode.Font;
            base.ClientSize = new Size(0x184, 0x113);
            base.Controls.Add(this.ProcessView);
            this.DoubleBuffered = true;
            base.Name = "Example";
            this.Text = "Cpu usage the API way";
            base.ResumeLayout(false);
        }

        private ProcessData ProcessExists(uint ID)
        {
            foreach (ProcessData data in this.ProcessDataList)
            {
                if (data.ID == ID)
                {
                    return data;
                }
            }
            return null;
        }

        private bool ProcessUpdated(uint ID)
        {
            foreach (uint num in this.IDList)
            {
                if (num == ID)
                {
                    return true;
                }
            }
            return false;
        }

        private void UsageTimer_Tick(object sender, EventArgs e)
        {
            this.GetUsage();
        }
    }
}

